package org.binglan.youziyuepai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.binglan.youziyuepai.entity.*;
import org.binglan.youziyuepai.enums.code.AcceptDatePatConditionEnum;
import org.binglan.youziyuepai.enums.code.AllowEnum;
import org.binglan.youziyuepai.enums.code.StatusEnum;
import org.binglan.youziyuepai.exception.MyException;
import org.binglan.youziyuepai.mapper.ActivityMapper;
import org.binglan.youziyuepai.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.binglan.youziyuepai.utils.EnumUtils;
import org.binglan.youziyuepai.vo.*;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.PropertyAccessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 活动表 服务实现类
 * </p>
 *
 * @author sanjin
 * @since 2019-04-09
 */
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements ActivityService {

    @Autowired
    ActivityToOccupationService activityToOccupationService;

    @Autowired
    ActivityToImageService activityToImageService;

    @Autowired
    ImageService imageService;

    @Autowired
    ActivityToUserService activityToUserService;

    @Autowired
    UserService userService;

    @Autowired
    OccupationService occupationService;


    // TODO 关于事务传播级别，此处可能有些问题
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Boolean saveActivity(List<ActivityToOccupation> activityToOccupationList, List<ActivityToImage> activityToImageList, Activity activity) {
        // 默认创建活动需要审核才能通过
        activity.setIsAllow(AllowEnum.NOT_ALLOW.getCode());
        baseMapper.insert(activity);

        // 保存场地图片
        activityToImageService.saveActivityToImageBatch(activityToImageList, activity.getId());

        // 保存人员人数
        activityToOccupationService.saveActivityToOccupationBatch(
                activityToOccupationList.stream().map(item -> {
                    return item.setActivityId(activity.getId());
                }).collect(Collectors.toList())
        );
        return true;
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ActivityVo queryActivityVoById(Integer id) {
        // 需要返回对象
        ActivityVo activityVo = new ActivityVo();

        Activity activity = new Activity();
        activity.setId(id);
        Activity getActivity = getOne(new QueryWrapper<>(activity));
        if (getActivity == null) return null;

        // 获取活动发布者信息
        UserVo userVo = userService.queryUserVoByUserId(getActivity.getUserId());

        List<Image> images = imageService.queryImagesByActivityId(id);

        List<ActivityToOccupation> activityToOccupationList = activityToOccupationService.queryActivityToOccupationsByActivityId(activity.getId());

        // 活动所需职业id ，人数 num

        // 活动id，获取参加活动的 userId
        List<ActivityToUser> activityToUserList = activityToUserService.queryActivityToUsersByActivityId(id);
        List<ActivityToOccupationVo> activityToOccupationVos = activityToOccupationList.stream().map(activityToOccupation -> {
            ActivityToOccupationVo obj = new ActivityToOccupationVo();
            Integer occupationId = activityToOccupation.getOccupationId();
            obj.setOccupationName(occupationService.queryNameById(occupationId));
            obj.setNum(activityToOccupation.getNum());
            List<String> userIds = new LinkedList<>();
            // 找到该职业对应的用户,并且该用户申请状态为接受
            activityToUserList.forEach(activityToUser -> {
                if (activityToUser.getOccupationId().equals(occupationId))
                    if (activityToUser.getStatus().equals(StatusEnum.ACCEPT.getCode()))
                        userIds.add(activityToUser.getUserId());
            });
            // 获取所有参加人员的userId
            obj.setUserVos(userIds.stream().map(userId -> {
                return userService.queryUserVoByUserId(userId);
            }).collect(Collectors.toList()));
            return obj;
        }).collect(Collectors.toList());


        BeanUtils.copyProperties(getActivity, activityVo);

        activityVo.setUserVo(userVo);
        activityVo.setImages(images);
        activityVo.setActivityToOccupationVos(activityToOccupationVos);

        return activityVo;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Activity queryActivityById(Integer id) {
        Activity activity = new Activity();
        activity.setId(id);
        return getOne(new QueryWrapper<>(activity));
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public boolean deleteActivityByActivityId(Integer activityId, String userId) {
        Activity activity = this.queryActivityById(activityId);
        if (!activity.getUserId().equals(userId)) {
            return false;
        }
        return this.removeById(activityId);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public boolean addUserToActivity(String userId, Integer activityId, Integer occupationId) {
        // 用户 id 通过 shiro 判断,必定存在
        Activity activity = this.queryActivityById(activityId);
        User joinUser = userService.queryUserById(userId);
        if (!occupationService.isExistsIds(Collections.singletonList(occupationId))) {
            throw new MyException("occupationId 不存在");
        }
        if (activity == null)
            throw new MyException("activityId 不存在");
        // 判断用户,是否是活动发布者，或者用户是否已经加入该活动
        if (userId.equals(activity.getUserId())) {
            throw new MyException("您是活动发布者，不能加入自己发布的活动");
        }
        if (activityToUserService.isExistsActivityToUserByUserIdAndActivityId(userId,activityId)) {
            throw new MyException("您已经参加了该活动");
        }
        // 用户加入活动
        ActivityToUser activityToUser = new ActivityToUser();
        activityToUser.setUserId(userId);
        activityToUser.setActivityId(activityId);
        activityToUser.setOccupationId(occupationId);
        activityToUser.setStatus(StatusEnum.IGNORE.getCode());
        boolean saveActivityToUser = activityToUserService.saveActivityToUser(activityToUser);
        return saveActivityToUser;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public boolean quitUserToActivity(String userId, Integer activityId) {
        // 判断活动是否存在
        Activity activity = this.queryActivityById(activityId);
        if (activity == null) {
            throw new MyException("活动不存在");
        }
        // 判断用户是否已经加入活动
        ActivityToUser activityToUser = activityToUserService.queryActivityToUsersByActivityId(userId, activityId);
        if (activityToUser == null){
            throw new MyException("您还没有加入该活动");
        }
        // 用户退出活动
        boolean deleteActivityToUserById = activityToUserService.deleteActivityToUserById(activityToUser.getId());
        return deleteActivityToUserById;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PageVo<ActivityVo> queryActivityVoByPage(Page<Activity> page, Integer isAllow) {
        IPage<Activity> activityIPage = this.baseMapper.queryActivityByPage(page, isAllow);
        PageVo<ActivityVo> pageVo = new PageVo<>();
        // 总数量
        pageVo.setCount(this.queryCount(isAllow));
        // 当前页码
        pageVo.setCurrent(page.getCurrent());
        // 每页数据量
        pageVo.setSize(page.getSize());
        // 总页数
        pageVo.setTotal(pageVo.getCount() / page.getSize());

        List<Activity> records = activityIPage.getRecords();
        List<ActivityVo> activityVos = new ArrayList<>(records.size());

        records.forEach(a -> {
            ActivityVo vo = this.queryActivityVoById(a.getId());
            activityVos.add(vo);
        });
        pageVo.setRows(activityVos);
        return pageVo;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public long queryCount(Integer isAllow) {
        Activity activity = new Activity();
        activity.setIsAllow(isAllow);
        int count = this.count(new QueryWrapper<>(activity));
        return count;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ActivityVo> getUserJoinActivitys(String userId) {

        // 申请状态(0 未查看,1 接受, 2 拒绝)
        List<ActivityToUser> activityToUsers = activityToUserService.queryActivityToUsersByUserId(userId, 1);

        List<ActivityVo> activityVos = new ArrayList<>();

        activityToUsers.forEach(au -> {
            ActivityVo vo = this.queryActivityVoById(au.getActivityId());
            activityVos.add(vo);
        });
        return activityVos;
    }

}
